<?php
/**
 * This class is responsible for profiling a forage instance.
 * 
 * @author Rob Young <rob@roryoung.co.uk>
 * @package forage.util
 */
class ForageProfiler
{
  private $timers;

  public function __construct()
  {
    $this->timers = array();
  }

  public function start($name)
  {
    if (!isset($this->timers[$name])) {
      $this->timers[$name] = array();
    }
    $this->timers[$name][] = $this->getMicrotime();
  }

  public function stop($name)
  {
    if (!isset($this->timers[$name]) || !$this->timers[$name]) {
      throw new ForageProfilerException('Stop called before start');
    }
    if (!isset($this->timer_data[$name])) {
      $this->initTimerData($name);
    }
    $this->timer_data[$name]['total'] += ($this->getMicrotime() - array_pop($this->timers[$name]));
    $this->timer_data[$name]['hits']++;
  }

  public function total($name)
  {
    if ($this->hasData($name)) {
      return $this->timer_data[$name]['total'];
    } else {
      return 0;
    }
  }

  public function average($name)
  {
    if ($this->hasData($name)) {
      return $this->timer_data[$name]['total'] / $this->timer_data[$name]['hits'];
    } else {
      return 0;
    }
  }

  public function hits($name)
  {
    if ($this->hasData($name)) {
      return $this->timer_data[$name]['hits'];
    } else {
      return 0;
    }
  }

  public function rate($name)
  {
    if ($this->hasData($name)) {
      return $this->timer_data[$name]['hits'] / $this->timer_data[$name]['total'];
    } else {
      return 0;
    }
  }

  private function hasData($name)
  {
    return isset($this->timer_data[$name]);
  }

  private function getMicrotime()
  {
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
  }

  private function initTimerData($name)
  {
    $this->timer_data[$name] = array(
      'total' => 0,
      'hits'  => 0
    );
  }
}

/**
 * Profiler exception
 *
 * @package forage.util
 */
class ForageProfilerException extends Exception {}
